Skip to content

feat: add ctrl+c cancellation on running pw-checks/tests#1292

Open
ferrandiaz wants to merge 25 commits into
next/v8from
ferran/red-375-cli-ctrlc-during-checkly-pw-test-cancel-test-session
Open

feat: add ctrl+c cancellation on running pw-checks/tests#1292
ferrandiaz wants to merge 25 commits into
next/v8from
ferran/red-375-cli-ctrlc-during-checkly-pw-test-cancel-test-session

Conversation

@ferrandiaz
Copy link
Copy Markdown
Contributor

@ferrandiaz ferrandiaz commented Apr 28, 2026

Affected Components

  • CLI
  • Create CLI
  • Test
  • Docs
  • Examples
  • Other

Notes for the Reviewer

Pressing Ctrl-C during checkly pw-test, checkly test, or checkly trigger now cancels the in-flight test session server-side via a new /v1/cancel REST endpoint, instead of silently killing the CLI and leaving the remote session running.

Motivation

Before this change, Ctrl-C terminated the CLI without signalling the backend — the remote session kept consuming cloud resources with no way to stop it.

What changed

  • New Cancel REST client (rest/cancel.ts) — POST /v1/cancel via cancelTestSession and cancelCheckSession; registered as api.cancel in api.ts
  • SIGINT handler in AbstractCheckRunner — on first Ctrl+C: emits Events.CANCEL and the reporter shows a cancellation message with a --detach hint; on second Ctrl+C: force-exits with code 1. Pre-existing SIGINT listeners (from when-exit, a transitive dependency) are removed during the run and restored afterward to prevent them from terminating the process on Windows.
  • --detach flag — when used, first Ctrl+C shows "Checks will continue running in the cloud." and exits cleanly with code 0 (checks keep running server-side)
  • Three CLI commands (pw-test, test, trigger) wire Events.CANCEL and Events.DETACH to reporters and the cancel API
  • Reporters — new onCancel / onDetach lifecycle on the Reporter interface; cancellation/detach messages rendered as part of the live summary panel; CheckStatus.CANCELLED with symbol; cancelled-count in summary line

Tests

Unit tests across cancel client (4), runner SIGINT lifecycle (9), reporter cancel/detach UI (4), util (24).

Notes

  • cancelCheckSession is wired but not called from any command in this PR — reserved for a future integration
  • Any custom Reporter implementations outside this repo need stubs for onCancel() and onDetach()

@ferrandiaz ferrandiaz added the build Issue regarding building and packaging label Apr 28, 2026
@github-actions

This comment has been minimized.

@ferrandiaz ferrandiaz added build Issue regarding building and packaging and removed build Issue regarding building and packaging labels May 7, 2026
@github-actions

This comment has been minimized.

@ferrandiaz ferrandiaz added canary:cancel build Issue regarding building and packaging and removed build Issue regarding building and packaging labels May 8, 2026
@github-actions

This comment has been minimized.

@ferrandiaz ferrandiaz added build Issue regarding building and packaging and removed build Issue regarding building and packaging labels May 13, 2026
@github-actions

This comment has been minimized.

@ferrandiaz ferrandiaz added build Issue regarding building and packaging and removed build Issue regarding building and packaging labels May 14, 2026
@github-actions
Copy link
Copy Markdown

🎉 Experimental release successfully published on npm

npm install [email protected]

ferrandiaz added 15 commits May 20, 2026 18:42
Adds an isCancelling flag to AbstractListReporter so the live status panel
stops re-rendering while the cancel confirmation prompt is on screen, and
resumes when the prompt closes.

- onCancelPromptShown clears the panel and raises the flag.
- onCancelPromptHidden lowers the flag and repaints; runs on both confirm
  and decline so live updates resume during the cancellation drain.
- _printSummary and onStreamLogs short-circuit while the flag is up.
- _clearSummary becomes a no-op when there is nothing to erase, preserving
  the clear/print invariant if a guard skips the paired _printSummary.
PQueue.pause() does not interrupt an in-flight handler. A CHECK_INPROGRESS
handler that started before SIGINT could still emit and trigger a panel
re-render right under the cancel prompt, producing spurious project-tree
output.

- Emit CANCEL_PROMPT_SHOWN before queue.pause(); EventEmitter.emit is
  synchronous so reporters set their flag before any pending handler can
  render.
- Emit CANCEL_PROMPT_HIDDEN after the prompt resolves on both confirm and
  decline, restoring live updates.
- On confirm, print 'Cancelling test session...' so the user sees feedback
  while the backend cancellation completes.
- Always queue.start() after the prompt: drains MQTT results so
  allChecksFinished can resolve on confirm, resumes normal flow on decline.
- Use printLn instead of raw process.stdout.write to match the rest of the
  CLI.
Wires the runner's CANCEL_PROMPT_SHOWN and CANCEL_PROMPT_HIDDEN events to
each reporter for the test, pw-test, and trigger commands.
Covers happy paths (clear-then-repaint, normal render before/after the
prompt) and edge cases (empty _clearString no-op, double prompt-shown
idempotency, prompt-hidden without prior prompt-shown, suppression of
_printSummary and onStreamLogs while cancelling).
Comment thread packages/cli/e2e/__tests__/cancel-prompt.spec.ts Outdated
sorccu and others added 2 commits May 20, 2026 19:03
The fixture doesn't import any project code — it only tests prompts
library behavior, which is already covered by the abstract-check-runner
unit tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@sorccu sorccu force-pushed the ferran/red-375-cli-ctrlc-during-checkly-pw-test-cancel-test-session branch from fff12f3 to e5ab7af Compare May 20, 2026 10:16
@sorccu sorccu changed the base branch from main to next/v8 May 20, 2026 10:17
@sorccu sorccu marked this pull request as ready for review May 20, 2026 10:19
sorccu and others added 5 commits May 20, 2026 19:29
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
The interactive confirmation prompt on Ctrl+C broke on Windows due to
cmd.exe's competing "Terminate batch job" dialog and the `when-exit`
transitive dependency (conf → atomically → when-exit) preempting the
SIGINT handler.

Now Ctrl+C always cancels immediately and suggests --detach for keeping
checks running. Uses prependListener to run before when-exit's handler.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
…ve prompt

The interactive confirmation prompt on Ctrl+C conflicted with cmd.exe's
"Terminate batch job" prompt on Windows, and a transitive dependency
(when-exit via conf → atomically) preempted the SIGINT handler by
re-raising SIGINT, which is a hard kill on Windows.

Replace the prompt with immediate cancellation: first Ctrl+C emits
CANCEL and shows a message suggesting --detach, second Ctrl+C force
exits. The cancellation message is rendered by the reporter as part of
its live summary panel so it doesn't get overwritten. Pre-existing
SIGINT listeners are removed during the run and restored afterward to
prevent when-exit from terminating the process.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Ctrl+C with --detach now shows "Checks will continue running in the
cloud." before exiting, instead of silently terminating.

Also refactors the SIGINT handler setup: both detach and non-detach
modes share the same when-exit listener removal and registration code,
with the mode-specific behavior inside the handler body.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
The cancel endpoint returns 403 when the account doesn't have the
feature flag set. Silently ignore it since cancellation is best-effort.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build Issue regarding building and packaging canary:cancel

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants